﻿using QxFramework.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

namespace GameControl
{
    public class ItemFuncManager : LogicModuleBase, IItemFuncManager
    {
        List<FuncField> funcList;
        //List<ItemFunc> funcSettingList;
        Dictionary<Tuple<string, string>, ItemFunc> funcSettingDic = new Dictionary<Tuple<string, string>, ItemFunc>();
        List<Tuple<KeyCode, KeyState>> keyList;
        public override void Init(object args)
        {
            base.Init(args);
            funcList = args as List<FuncField>;
            //funcSettingList = new List<ItemFunc>();
            /*foreach(var x in funcList)
            {
                funcSettingList.Add(GameManager.Get<IItemInstantiateManager>().GetItemSettingByName(x.BelongingItemName.Split('_')[0]).getc)
            }*/
            var list = Resources.LoadAll<GameObject>("Prefabs/Item/");
            foreach (var x in list)
            {
                var f = x.GetComponents<ItemFunc>();
                foreach(var y in f)
                {
                    funcSettingDic[new Tuple<string, string>(x.name, y.GetType().ToString())] = y;
                }
            }
            keyList = new List<Tuple<KeyCode, KeyState>>();
            MessageManager.Instance.Get<ItemFuncEvent>().RegisterHandler(ItemFuncEvent.OnChangeKey, ChangeKey);
            MessageManager.Instance.Get<GameControl.ItemFuncEvent>().RegisterHandler(GameControl.ItemFuncEvent.OnKey, ReceiveKey);
      //      MessageManager.Instance.Get<ItemFuncEvent>().RegisterHandler(ItemFuncEvent.ClearOnKeyInfo, (object sender, EventArgs e) => { keyList.Clear();
      //          return null;
     //      });
        }
        EventArgs ChangeKey(object sender,EventArgs e)
        {
            var tp = e as ItemFuncArgs;
            var func = funcList.Find(s => s.BelongingItemName == tp.BelongItemName && s.FuncTypeName== tp.FuncTypeName);
            func.Key = tp.NewKey;
            MessageManager.Instance.Get<ItemFuncEvent>().DispatchMessage(ItemFuncEvent.DoneChangeKey, this, null);
            return null;
        }
        public void AddFuncField(Item itemSetting,string itemInstanceName)
        {
            var list = itemSetting.GetComponentsInChildren<ItemFunc>();
            foreach(var x in list)
            {
                if (funcList.Find(s => s.BelongingItemName == itemInstanceName && s.FuncTypeName==x.GetType().ToString()) != null)
                {

                    Debug.LogError("相同技能重复出现在同一物体上");
                }
                funcList.Add(new FuncField
                {
                    BelongingItemName = itemInstanceName,
                    FuncTypeName = x.GetType().ToString(),
                    Key=KeyCode.None
                });
           //     funcSettingList.Add(x);
            }
        }

        public List<FuncField> GetFuncFieldAbout(string item)
        {
            return funcList.FindAll(s => s.BelongingItemName == item);
        }
        public  ItemFunc GetFuncSettingAbout(FuncField func)
        {
            if (funcSettingDic.ContainsKey(new Tuple<string, string>(func.BelongingItemName.Split('_')[0], func.FuncTypeName)))
            {
                return funcSettingDic[new Tuple<string, string>(func.BelongingItemName.Split('_')[0], func.FuncTypeName)];
            }
            Debug.LogError("没有找到相关的函数设置");
            return null;
        //    Debug.Assert(funcSettingList.FindAll(s=>s.GetType()==func.FuncType&&s.gameObject.name==))
        }
        public void RemoveFuncAbout(string item)
        {
            funcList.RemoveAll(s => (s.BelongingItemName == item));
        }


        public EventArgs ReceiveKey(object sender, EventArgs e)
        {
            keyList.UniqueAdd((e as UniversalEventArgs).Info as Tuple<KeyCode, KeyState>);
            return null;
        }
        public void UpdateFunc()
        {
            var upList = keyList.FindAll(s => s.Item2 == KeyState.Up);
            foreach(var x in upList)
            {
                keyList.RemoveAll(s => s.Item1 == x.Item1 && s.Item2 == KeyState.On);
            }


                foreach (var key in keyList)
                {

                    var list = funcList.FindAll(s => s.Key == key.Item1);
                    foreach(var x in list)
                    {
                        var obj = ClockManager.Get<IItemSyncManager>().GetGameObjectByName(x.BelongingItemName);
                        if (!obj) continue;
                        var funcs = obj.GetComponent<CombinableItem>().FuncList.FindAll(s => s.GetType().ToString() == x.FuncTypeName);
                        foreach(var f in funcs)
                        {
                            if (key.Item2 == KeyState.Down)
                            {
                                f.KeyDownInvoke();
                                f.KeyDownPreference();
                            }
                            if (key.Item2 == KeyState.On)
                            {
                                f.KeyOnInvoke();
                                f.KeyOnPreference();
                            }
                            if (key.Item2 == KeyState.Up)
                            {
                                f.KeyUpInvoke();
                                f.KeyUpPreference();
                            }
                        }

                    }
                }
            //      keyList.Clear();
            keyList.RemoveAll(s => s.Item2 == KeyState.Down || s.Item2 == KeyState.Up);
        }
        /*      public void UpdateFunc()
              {
                  foreach(var x in _actionList)
                  {
                      try
                      {
                          switch (x.Item3)
                          {
                              case KeyState.On:
                                  if (InputManager.Instance.GetKey(x.Item2))
                                  {
                                      x.Item1();
                                  }
                                  break;
                              case KeyState.Up:
                                  if (InputManager.Instance.GetKeyUp(x.Item2))
                                  {
                                      x.Item1();
                                  }
                                  break;
                              case KeyState.Down:
                                  if (InputManager.Instance.GetKeyDown(x.Item2))
                                  {
                                      x.Item1();
                                  }
                                  break;
                              default:
                                  throw new Exception($"{this.GetType().Name}:按键状态不存在");
                          }
                      }
                      catch(Exception e)
                      {
                          Debug.LogError(e);
                      }
                  }
              }*/
    }
    public enum ItemFuncEvent
    {
        OnChangeKey,
        DoneChangeKey,
        OnKey,
    //    ClearOnKeyInfo

    }
    public class ItemFuncArgs:EventArgs
    {
        public string FuncTypeName;
        public string BelongItemName;
        public KeyCode NewKey;
    }
    interface IItemFuncManager
    {
        void AddFuncField(Item itemSetting,string itemInstanceName);
        List<FuncField> GetFuncFieldAbout(string item);
        ItemFunc GetFuncSettingAbout(FuncField func);
        void RemoveFuncAbout(string  item);
        void UpdateFunc();
    }
}